{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "        <style>\n",
       "        .output_wrapper, .output {\n",
       "            height:auto !important;\n",
       "            max-height:100000px; \n",
       "        }\n",
       "        .output_scroll {\n",
       "            box-shadow:none !important;\n",
       "            webkit-box-shadow:none !important;\n",
       "        }\n",
       "        </style>\n",
       "    "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#format the book\n",
    "from __future__ import division, print_function\n",
    "%matplotlib inline\n",
    "import sys\n",
    "sys.path.insert(0, '..')\n",
    "import book_format\n",
    "book_format.set_style()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linearizing with Taylor Series\n",
    "\n",
    "Taylor series represents a function as an infinite sum of terms. The terms are linear, even for a nonlinear function, so we can express any arbitrary nonlinear function using linear algebra. The cost of this choice is that unless we use an infinite number of terms the value we compute will be approximate rather than exact.\n",
    "\n",
    "The Taylor series for a real or complex function f(x) at x=a is the infinite series\n",
    "\n",
    "$$f(x) = f(a) + f'(a)(x-a) + \\frac{f''(a)}{2!}(x-a)^2 + \\, ...\\,  + \\frac{f^{(n)}(a)}{n!}(x-a)^n + \\, ...$$\n",
    "\n",
    "where $f^{n}$ is the nth derivative of f. To compute the Taylor series for $f(x)=sin(x)$ at $x=0$ let's first work out the terms for f.\n",
    "\n",
    "$$\\begin{aligned}\n",
    "f^{0}(x) &= sin(x) ,\\ \\  &f^{0}(0) &= 0 \\\\\n",
    "f^{1}(x) &= cos(x),\\ \\  &f^{1}(0) &= 1 \\\\\n",
    "f^{2}(x) &= -sin(x),\\ \\  &f^{2}(0) &= 0 \\\\\n",
    "f^{3}(x) &= -cos(x),\\ \\  &f^{3}(0) &= -1 \\\\\n",
    "f^{4}(x) &= sin(x),\\ \\  &f^{4}(0) &= 0 \\\\\n",
    "f^{5}(x) &= cos(x),\\ \\  &f^{5}(0) &= 1\n",
    "\\end{aligned}\n",
    "$$\n",
    "\n",
    "Now we can substitute these values into the equation.\n",
    "\n",
    "$$\\sin(x) = \\frac{0}{0!}(x)^0 + \\frac{1}{1!}(x)^1 + \\frac{0}{2!}(x)^2 + \\frac{-1}{3!}(x)^3 + \\frac{0}{4!}(x)^4 + \\frac{-1}{5!}(x)^5 + ... $$\n",
    "\n",
    "And let's test this with some code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "estimate of sin(.3) is 0.30452025\n",
      "exact value of sin(.3) is 0.29552020666133955\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "x = .3\n",
    "estimate = x + x**3/6 + x**5/120\n",
    "exact = np.sin(.3)\n",
    "\n",
    "print('estimate of sin(.3) is', estimate)\n",
    "print('exact value of sin(.3) is', exact)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is not bad for only three terms. If you are curious, go ahead and implement this as a Python function to compute the series for an arbitrary number of terms."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
